import { debounce } from "lodash-es";
import { RefObject, useLayoutEffect, useRef, useState } from "react";
import { findObjByKey, useRefState } from "../../../common/utils";
import { IMUIColumnsType, SCROLLBAR_WIDTH, TABLE_COL_MIN_WIDTH } from "../common";

export const getNewColsWidth = (columns: IMUIColumnsType, columnWidths: any = {}) => {
    const newWidth: any = columnWidths
    const v = (arr: IMUIColumnsType) => {
        arr.forEach((item) => {
            const { dataIndex, width, children } = item
            const w = width
            if (children?.length) {
                v(children)
            } else {
                newWidth[dataIndex] = w
            }
        })
    }
    v(columns)
    return newWidth
}

// 获取纵向滚动条宽度
export const getTableScrollYWidth = (tableWrapRef: RefObject<HTMLDivElement>, data?: readonly any[]) => {
    // 给表格重新计算宽度时 空数据默认有滚动条(防止数据拿到后滚动条闪现)
    if (data && !data.length) return SCROLLBAR_WIDTH
    const wrappper = tableWrapRef.current?.querySelector(".mui-table")?.querySelector("div")
    const content = wrappper?.querySelector('.MuiTable-root')
    const { height: wrapperHeight = 0 } = wrappper?.getBoundingClientRect() || {}
    const { height: contentHeight = 0 } = content?.getBoundingClientRect() || {}
    return wrapperHeight < contentHeight ? SCROLLBAR_WIDTH : 0
}

const useTableResize = (columns: any[], selectionColWidth: number, data: any[]) => {
    const wrapRef = useRef<HTMLDivElement>(null)
    // 是否使用拖拽功能
    const [useResize, setUseResize] = useState<any>(false);

    // 表格显示的列
    const [showColumns, setShowColumns, showColumnsRef] = useRefState<any>(columns)

    useLayoutEffect(() => {
        setTimeout(() => {
            // 更新前后的 columns 显示的列不完全一样
            if (!isColsSame()) {
                resetTableCols()
            } else {
                // 一样时重新设置 showColumns 但保留现在的宽度
                refreshTableCols()
            }
            setTimeout(() => {
                setUseResize(true)
            }, 100)
        }, 200)
    }, [columns])
    // }, [columns, JSON.stringify(data)])

    // 判断更新前后的 columns 的列是否完全一样(除了宽度)
    const isColsSame = () => {
        // 和传进来的columns一样 还没计算过 
        if (showColumnsRef.current.length === columns?.length && showColumnsRef.current.every((col: any, index: number) => col.dataIndex === columns[index]?.dataIndex && col.width === columns[index]?.width)) return false
        // @ts-ignore
        return showColumnsRef.current.length === columns?.length && showColumnsRef.current.every((col: any, index: number) => col.dataIndex === columns[index]?.dataIndex)
    }

    const resetWidth = (colList: any[], getNewWidth: any): any[] => {
        return colList.map((col: any) => {
            if (!col.children?.length) return {
                ...col,
                width: getNewWidth(col),
            }
            return {
                ...col,
                children: resetWidth(col.children, getNewWidth),
            }
        })
    }

    // 获取表格总宽度
    const getColumnsTotalWidth = (showColumns: any[] = [], filter?: (col: any) => boolean): number => {
        return showColumns.reduce((pre: number, col: any) => {
            const { width = TABLE_COL_MIN_WIDTH, children } = col
            if (children?.length > 0) return pre + getColumnsTotalWidth(children, filter)
            if (filter && !filter(col)) return pre
            return pre + width
        }, 0)
    }

    // 获取某一列的宽度
    const getColWidth = (col: any) => {
        const { stretchDisabled, width = TABLE_COL_MIN_WIDTH } = col
        if (stretchDisabled) return width
        if (!col.width || !wrapRef.current?.clientWidth) return 0
        // 可拉伸的列
        const total1 = getColumnsTotalWidth(columns, (col: any) => !col.stretchDisabled)
        // 不拉伸的列
        const total2 = getColumnsTotalWidth(columns, (col: any) => !!col.stretchDisabled)
        // const total = getColumnsTotalWidth(columns)
        // -2 是边框
        const stretchWidth = wrapRef.current?.clientWidth - getTableScrollYWidth(wrapRef, data) - selectionColWidth - total2 - 2;
        if (!total1) return 0
        const newWidth = Number((stretchWidth * (col.width / total1))?.toFixed(2)) || 0
        // const originalWidth = findObjByKey(columns, col.dataIndex, "dataIndex")?.width || 0
        // return Math.max(newWidth, originalWidth)
        return Math.max(newWidth, width)
    }


    // 计算出每列的渲染宽度 并重新给width赋值
    const resetTableCols = debounce(() => {
        setShowColumns(resetWidth(columns, (col: any) => {
            return getColWidth(col)
        }))
    })

    // 重置cols 但保留现在的宽度
    const refreshTableCols = () => {
        setShowColumns(resetWidth(columns, (col: any) => {
            const lastCol = findObjByKey(showColumnsRef.current, col.dataIndex, "dataIndex")
            // return lastCol ? lastCol?.width : TABLE_COL_MIN_WIDTH
            return lastCol ? lastCol?.width : undefined
        }))
    }

    // 处理拖拽
    const handleResize = (col: any, newWidth: number) => {
        const v = (list: any[]): any[] => {
            return list.map((item: any) => {
                if (item.dataIndex === col.dataIndex) return {
                    ...item,
                    width: newWidth
                }
                if (item.children?.length) {
                    return {
                        ...item,
                        children: v(item.children)
                    }
                }
                return item
            })
        }
        const nextColumns = v(showColumnsRef.current)
        setShowColumns([...nextColumns])
    }

    return {
        useResize,
        wrapRef,
        showColumns,
        handleResize,
    }

}

export default useTableResize
